package com.luobo.behavior.strategy;

import org.springframework.beans.BeansException;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Order(1)
/**
 *容器启动完毕后执行该类
 */
public class Context implements ApplicationRunner, ApplicationContextAware {

    private ApplicationContext applicationContext;
    private static Map<String,Color> colorStrategy = new ConcurrentHashMap<>();

    public static Color getStrategy(String type){
        Color color = colorStrategy.get(type);
        if(color == null){
            throw new RuntimeException(type+"无法获取到Color");
        }
        return color;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        initStrategy();
    }

    /**
     * 初始化策略容器
     */
    private void initStrategy() {
        Collection<Color> strategyList = getApplicationContext().getBeansOfType(Color.class).values();
        for (Color strategy : strategyList) {
            Class<? extends Color> aClass = strategy.getClass();
            ColorAnnotation annotation = aClass.getAnnotation(ColorAnnotation.class);
            if (annotation != null) {
                colorStrategy.put(annotation.type(), strategy);
            }
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 获取applicationContext
     */
    private ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 通过name获取 Bean.
     */
    public Object getBean(String name){
        return getApplicationContext().getBean(name);
    }
    /**
     * 通过class获取Bean.
     */
    public <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     */
    public <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }

}
